
#include "stdafx.h"

TEST(getsockoptTest, getsockopt_in_inout)
{
    SOCKET sock = INVALID_SOCKET;
    int len = 4;//sizeof(int);
    
    Header header(GetCurrentThreadId(), "getsockopt");
    getsockopt_in_inout getsockoptIN(sock, SOL_SOCKET, SO_ACCEPTCONN, &len);
    getsockopt_in_inout getsockoptOUT;

    std::vector<char> buffer;
    Serialize(header, getsockoptIN, buffer);
        
    Deserialize deserialize(buffer);
    deserialize(getsockoptOUT);

    EXPECT_EQ (header.TID_, deserialize.get_header().TID_);
    EXPECT_EQ (header.func_name_, deserialize.get_header().func_name_);

    EXPECT_EQ (getsockoptIN.s_, getsockoptOUT.s_);
    EXPECT_EQ (getsockoptIN.level_, getsockoptOUT.level_);
    EXPECT_EQ (getsockoptIN.optname_, getsockoptOUT.optname_);
    if (getsockoptIN.optlen_ && getsockoptOUT.optlen_)
    {
        EXPECT_EQ (*getsockoptIN.optlen_, *getsockoptOUT.optlen_);
    }
    else {
        EXPECT_FALSE (getsockoptIN.optlen_);
        EXPECT_FALSE (getsockoptOUT.optlen_);
    }
}

TEST(getsockoptTest, getsockopt_in_inout_NULL_parameters)
{
    SOCKET sock = INVALID_SOCKET;
    
    Header header(GetCurrentThreadId(), "getsockopt");
    getsockopt_in_inout getsockoptIN(sock, SOL_SOCKET, SO_ACCEPTCONN, NULL);
    getsockopt_in_inout getsockoptOUT;

    std::vector<char> buffer;
    Serialize(header, getsockoptIN, buffer);
        
    Deserialize deserialize(buffer);
    deserialize(getsockoptOUT);

    EXPECT_EQ (header.TID_, deserialize.get_header().TID_);
    EXPECT_EQ (header.func_name_, deserialize.get_header().func_name_);

    EXPECT_EQ (getsockoptIN.s_, getsockoptOUT.s_);
    EXPECT_EQ (getsockoptIN.level_, getsockoptOUT.level_);
    EXPECT_EQ (getsockoptIN.optname_, getsockoptOUT.optname_);
    if (getsockoptIN.optlen_ && getsockoptOUT.optlen_)
    {
        EXPECT_EQ (*getsockoptIN.optlen_, *getsockoptOUT.optlen_);
    }
    else {
        EXPECT_FALSE (getsockoptIN.optlen_);
        EXPECT_FALSE (getsockoptOUT.optlen_);
    }
}

TEST(getsockoptTest, getsockopt_out_inout)
{
    SOCKET sock = INVALID_SOCKET;
    int optVal  = 11;
    int len = sizeof(int);

    Header header(GetCurrentThreadId(), "getsockopt");
    getsockopt_out_inout getsockoptIN((char*)&optVal, &len, 7);
    getsockopt_out_inout getsockoptOUT;

    std::vector<char> buffer;
    Serialize(header, getsockoptIN, buffer);
        
    Deserialize deserialize(buffer);
    deserialize(getsockoptOUT);

    EXPECT_EQ (header.TID_, deserialize.get_header().TID_);
    EXPECT_EQ (header.func_name_, deserialize.get_header().func_name_);

    if (getsockoptIN.optlen_ && getsockoptOUT.optlen_)
    {
        EXPECT_EQ (*getsockoptIN.optlen_, *getsockoptOUT.optlen_);
    }
    else {
        EXPECT_FALSE (getsockoptIN.optlen_);
        EXPECT_FALSE (getsockoptOUT.optlen_);
    }
    if (getsockoptIN.optval_ && getsockoptOUT.optval_)
    {
        int cmp = memcmp (getsockoptIN.optval_, getsockoptOUT.optval_,
                          *getsockoptIN.optlen_);
        EXPECT_TRUE (!cmp);
    }
    else {
        EXPECT_FALSE (getsockoptIN.optval_);
        EXPECT_FALSE (getsockoptOUT.optval_);
    }
    EXPECT_EQ (getsockoptIN.wsa_last_error_, getsockoptOUT.wsa_last_error_);
}

TEST(getsockoptTest, getsockopt_out_inout_NULL_parameters)
{
    SOCKET sock = INVALID_SOCKET;
    int optVal  = 11;
    int len = sizeof(int);

    Header header(GetCurrentThreadId(), "getsockopt");
    //getsockopt_out_inout getsockoptIN((char*)&optVal, NULL, 7);
    //getsockopt_out_inout getsockoptIN(NULL, &len, 7);
    getsockopt_out_inout getsockoptIN(NULL, NULL, 7);
    getsockopt_out_inout getsockoptOUT;

    std::vector<char> buffer;
    Serialize(header, getsockoptIN, buffer);
        
    Deserialize deserialize(buffer);
    deserialize(getsockoptOUT);

    EXPECT_EQ (header.TID_, deserialize.get_header().TID_);
    EXPECT_EQ (header.func_name_, deserialize.get_header().func_name_);

    if (getsockoptIN.optlen_ && getsockoptOUT.optlen_)
    {
        EXPECT_EQ (*getsockoptIN.optlen_, *getsockoptOUT.optlen_);
    }
    else {
        EXPECT_FALSE (getsockoptIN.optlen_);
        EXPECT_FALSE (getsockoptOUT.optlen_);
    }
    if (getsockoptIN.optval_ && getsockoptOUT.optval_)
    {
        int cmp = memcmp (getsockoptIN.optval_, getsockoptOUT.optval_,
                          *getsockoptIN.optlen_);
        EXPECT_TRUE (!cmp);
    }
    else {
        EXPECT_FALSE (getsockoptIN.optval_);
        EXPECT_FALSE (getsockoptOUT.optval_);
    }
    EXPECT_EQ (getsockoptIN.wsa_last_error_, getsockoptOUT.wsa_last_error_);
}